package api

import (
	"openapi.itspire.cn/common/dict"
	"openapi.itspire.cn/common/global"
	"openapi.itspire.cn/common/throw"
	"openapi.itspire.cn/database"
	"openapi.itspire.cn/model"
	"openapi.itspire.cn/utils"
	"github.com/gin-gonic/gin"
	"strconv"
)

func CategoryList(c *gin.Context) {
	categoryType, _ := strconv.Atoi(c.DefaultQuery("type", "0"))

	var category model.Category
	list := make([]*model.CategoryArticle, 0)
	query := database.Ins.
		Table(category.GetTableName() + " a").
		Select("a.id,a.category_name,count(b.id) count").
		Joins("left join "+model.Article{}.GetTableName()+" b on a.id = b.category_id").
		Where("a.pid = ? AND a.status = ? AND a.delete_time = ? AND b.status = ? AND b.delete_time = ?", categoryType, dict.StatusOn, dict.DeleteNot, dict.StatusOn, dict.DeleteNot).
		Group("b.category_id").
		Order("a.sort desc, a.id asc")
	if err := query.Scan(&list).Error; err != nil {
		throw.ServerError(c, err.Error())
		return
	}

	utils.Success(c, list)
}

func CategoryArticle(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	size := global.PageSize

	list := make([]*model.ArticleList, 0)
	total := 0

	var category model.Category
	res := database.Ins.Where("id = ? AND status = ? AND delete_time = ?", id, dict.StatusOn, dict.DeleteNot).First(&category)
	if res.RecordNotFound() == true {
		throw.NotFound(c, "记录不存在")
		return
	}

	if category.TypeId == dict.CategoryArticle {
		total, list = categoryArticle(c, list, total, id, page, size)
	} else if category.TypeId == dict.CategoryLabel {
		total, list = labelArticle(c, list, total, id, page, size)
	}

	maps := make(map[string]interface{})
	maps["pagination"] = map[string]int{"page": page, "size": size, "total": total}
	maps["list"] = list

	utils.Success(c, maps)
}

func categoryArticle(c *gin.Context, list []*model.ArticleList,  total int, id int, page int, size int) (total1 int, list1 []*model.ArticleList) {
	var article model.Article
	query := database.Ins.
		Model(&article).
		Where("category_id = ? AND status = ? AND delete_time = ?", id, dict.StatusOn, dict.DeleteNot)
	if err := query.Count(&total).Error; err != nil {
		throw.ServerError(c, err.Error())
		return
	}

	if total > 0 {
		query = database.Ins.
			Table(article.GetTableName()+" a").
			Select("a.id,a.title,a.category_id,a.introduction,a.comment_num,a.reading_num,a.is_top,a.publish_time,b.category_name").
			Joins("left join "+model.Category{}.GetTableName()+" b on a.category_id = b.id").
			Where("a.category_id = ? AND a.status = ? AND a.delete_time = ?", id, dict.StatusOn, dict.DeleteNot).
			Order("a.publish_time desc").
			Limit(size).
			Offset((page - 1) * size)
		if err := query.Scan(&list).Error; err != nil {
			throw.ServerError(c, err.Error())
			return
		}
		for _, v := range list {
			v.FormatTime = utils.FormatTime(v.PublishTime)
		}
	}

	return total, list
}

func labelArticle(c *gin.Context, list []*model.ArticleList,  total int, id int, page int, size int) (total1 int, list1 []*model.ArticleList) {
	var articleLabel model.ArticleLabel
	query := database.Ins.
		Table(articleLabel.GetTableName()+" a").
		Joins("left join "+model.Article{}.GetTableName()+" b on a.article_id = b.id").
		Where("a.label_id = ? AND b.status = ? AND b.delete_time = ?", id, dict.StatusOn, dict.DeleteNot)
	if err := query.Count(&total).Error; err != nil {
		throw.ServerError(c, err.Error())
		return
	}

	if total > 0 {
		query = database.Ins.
			Table(articleLabel.GetTableName()+" a").
			Select("b.id,b.title,b.category_id,b.introduction,b.comment_num,b.reading_num,b.is_top,b.publish_time,c.category_name").
			Joins("left join "+model.Article{}.GetTableName()+" b on a.article_id = b.id").
			Joins("left join "+model.Category{}.GetTableName()+" c on b.category_id = c.id").
			Where("a.label_id = ? AND b.status = ? AND b.delete_time = ?", id, dict.StatusOn, dict.DeleteNot).
			Order("b.publish_time desc").
			Limit(size).
			Offset((page - 1) * size)
		if err := query.Scan(&list).Error; err != nil {
			throw.ServerError(c, err.Error())
			return
		}
		for _, v := range list {
			v.FormatTime = utils.FormatTime(v.PublishTime)
		}
	}

	return total, list
}
